/*
 * Copyright (c) 2009-2013 EvTech Project
 * All rights reserved.
 * 
 * This file is part of Symbol Matching.
 *
 * Symbol Matching is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or 
 * (at your option) any later version.
 *
 * Symbol Matching is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Symbol Matching.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */
package fi.honkalampisaatio.reaktiopeli.game;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.KeyEventDispatcher;
import java.awt.KeyboardFocusManager;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;

import javax.sound.sampled.Clip;
import javax.xml.bind.JAXBException;

import fi.honkalampisaatio.game.game.LanguageResource;
import fi.honkalampisaatio.game.utilities.MediaLoader;
import fi.honkalampisaatio.game.xml.KeyValuePair;
import fi.honkalampisaatio.game.xml.LanguageSettings;
import fi.honkalampisaatio.game.xml.SettingsReader;
import fi.honkalampisaatio.game.xml.Setup;
import fi.honkalampisaatio.game.xml.UserSetting;
import fi.honkalampisaatio.reaktiopeli.ReaktioPeli;
import fi.honkalampisaatio.reaktiopeli.setup.SetupData;
import fi.honkalampisaatio.reaktiopeli.xml.ChoiceButton;
import fi.honkalampisaatio.reaktiopeli.xml.HighScore;
import fi.honkalampisaatio.reaktiopeli.xml.ReactionGameSettings;
import fi.honkalampisaatio.reaktiopeli.xml.GameDifficulty.DIFFICULTY;


public class GamePanel extends fi.honkalampisaatio.game.game.GamePanel {

	private static final long serialVersionUID = -3096074614191175372L;
	
	public static int MAX_IMAGE_SIZE = 600;
	
	private GameRunner gr;
	
	private ChoicePanel cp;
	private PlayersPanel playersPanel;
	private QuestionPanel questionPanel;
	private HighScorePanel highscorePanel;
	
	private boolean showCp, showPlayersPanel, showQuestionPanel;
	
	private GameInstructionsPanel gameInstructionsPanel;
	private GameOptionsPanel gameOptionsPanel;
	
	private MidiSounds midiSounds;
	private BufferedImage correctAnswerImg;

	private int whoIsUsingTheMouse=0;
	private int choiceCount;
	
	private Clip endClip;

	public static int NO_ONE   = 0;
	public static int PLAYER_1 = 1;
	public static int PLAYER_2 = 2;
	
	protected Setup setupData;
	
	
	public GamePanel()
	{
		super(ReactionGameSettings.class);
	}
	
	
	@Override
	public void init(Setup setupData) {
		this.setupData = setupData;
		choiceCount = 0;
		midiSounds = new MidiSounds();
		cp = new ChoicePanel();
		this.add(cp);
		cp.setVisible(false);
		this.gr = new GameRunner(this);
		KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
		manager.addKeyEventDispatcher(new KeyEventDispatcher() {
			@Override
			public boolean dispatchKeyEvent(KeyEvent event) {
				if(event.isAltDown() && event.getKeyCode()==KeyEvent.VK_F4) {	
					gr.shutdown();
					return true;
				}
				return false;
			}});
/*
		timeMeter = new MeterPanel();
		this.add(timeMeter);
		timeMeter.setBounds((int)(this.getWidth()*0.05), (int)(this.getHeight()*0.05), 
				(int)(this.getWidth()*0.9), (int)(this.getHeight()*0.05));
		timeMeter.setVisible(false);
		*/
		gameOptionsPanel = new GameOptionsPanel();
		gameOptionsPanel.addSetupEventListener(this.gr);
		//this.add(optionsPanel, 0);
		this.add(gameOptionsPanel);
		this.addKeyListener(gameOptionsPanel);
		gameOptionsPanel.setVisible(false);
		gameOptionsPanel.setPreferredSize(Toolkit.getDefaultToolkit().getScreenSize());

		gameInstructionsPanel = new GameInstructionsPanel();
		gameInstructionsPanel.addSetupEventListener(this.gr);
		this.add(gameInstructionsPanel);
		//this.addKeyListener(gameInstructionsPanel);
		gameInstructionsPanel.setVisible(false);
		gameInstructionsPanel.setPreferredSize(Toolkit.getDefaultToolkit().getScreenSize());
		
		playersPanel = new PlayersPanel(cp);
		this.add(playersPanel);
		playersPanel.setBounds((int)(this.getWidth()*0.05), (int)(this.getHeight()*0.1), 
				(int)(this.getWidth()*0.9), (int)(this.getHeight()*0.1));
		playersPanel.setVisible(false);
		
		
		questionPanel = new QuestionPanel();
		this.add(questionPanel);
		questionPanel.setBounds((int)(this.getWidth()*0.05), (int)(this.getHeight()*0.21), 
				(int)(this.getWidth()*0.9), (int)(this.getHeight()*0.6));
		questionPanel.setVisible(false);
		//this.setLocation(0, 0);
		//this.setSize(Toolkit.getDefaultToolkit().getScreenSize());
		
		highscorePanel = new HighScorePanel();
		this.add(highscorePanel);
		highscorePanel.setVisible(false);
		highscorePanel.setPreferredSize(Toolkit.getDefaultToolkit().getScreenSize());
		highscorePanel.addTargetEventListener(gr);
		this.setComponentZOrder(highscorePanel, 0);
		

		if(this.setupData!=null && this.setupData.getBackButton()!=null
				&& this.setupData.getBackButton().getImage()!=null)
		{
			gameOptionsPanel.setBackButtonIcon(this.setupData.getBackButton().getImage());
			gameInstructionsPanel.setBackButtonIcon(this.setupData.getBackButton().getImage());
		}
		if(this.setupData!=null)
		{
			BufferedImage correctImg, wrongImg;
			correctImg = MediaLoader.createImage(this.setupData.getCorrectAnswerImage(), MAX_IMAGE_SIZE, MAX_IMAGE_SIZE);
			wrongImg = MediaLoader.createImage(this.setupData.getWrongAnswerImage(), MAX_IMAGE_SIZE, MAX_IMAGE_SIZE);
			playersPanel.setFeedbackImages(correctImg, wrongImg);
			
			gameInstructionsPanel.setOptionsButtonVisibile(this.setupData.getShowOptionsButton());
		}
		endClip = MediaLoader.createSoundClip("./aanet/applause-2.wav");
	}

	public void setComponentsBounds() {
		/*
		timeMeter.setBounds((int)(getWidth()*0.02), (int)(this.getHeight()*0.02), 
				(int)(getWidth()*0.96), (int)(this.getHeight()*0.05));
		if(showTimeMeter)
		{
			playersPanel.setBounds((int)(this.getWidth()*0.02), (int)(this.getHeight()*0.08), 
					(int)(this.getWidth()*0.96), (int)(this.getHeight()*0.1));	
			if(showCp)
			{
				questionPanel.setBounds((int)(this.getWidth()*0.02), (int)(this.getHeight()*0.19), 
						(int)(this.getWidth()*0.96), (int)(this.getHeight()*0.63));	
			}
			else
			{
				questionPanel.setBounds((int)(this.getWidth()*0.02), (int)(this.getHeight()*0.19), 
						(int)(this.getWidth()*0.96), (int)(this.getHeight()*0.79));	
			}
			cp.setBounds((int)(getWidth()*0.02), (int)(this.getHeight()*0.83), 
					(int)(getWidth()*0.96), (int)(this.getHeight()*0.15));
		}
		else
		{
			playersPanel.setBounds((int)(this.getWidth()*0.02), (int)(this.getHeight()*0.02), 
					(int)(this.getWidth()*0.96), (int)(this.getHeight()*0.1));	
			if(showCp)
			{
				questionPanel.setBounds((int)(this.getWidth()*0.02), (int)(this.getHeight()*0.13), 
						(int)(this.getWidth()*0.96), (int)(this.getHeight()*0.69));	
			}
			else
			{
				questionPanel.setBounds((int)(this.getWidth()*0.02), (int)(this.getHeight()*0.13), 
						(int)(this.getWidth()*0.96), (int)(this.getHeight()*0.85));	
			}	
			cp.setBounds((int)(getWidth()*0.02), (int)(this.getHeight()*0.83), 
					(int)(getWidth()*0.96), (int)(this.getHeight()*0.15));
		}
		*/
		playersPanel.setBounds((int)(this.getWidth()*0.02), (int)(this.getHeight()*0.02), 
				(int)(this.getWidth()*0.96), (int)(this.getHeight()*0.1));	
		if(showCp)
		{
			questionPanel.setBounds((int)(this.getWidth()*0.02), (int)(this.getHeight()*0.13), 
					(int)(this.getWidth()*0.96), (int)(this.getHeight()*0.69));	
		}
		else
		{
			questionPanel.setBounds((int)(this.getWidth()*0.02), (int)(this.getHeight()*0.13), 
					(int)(this.getWidth()*0.96), (int)(this.getHeight()*0.85));	
		}	
		cp.setBounds((int)(getWidth()*0.02), (int)(this.getHeight()*0.83), 
				(int)(getWidth()*0.96), (int)(this.getHeight()*0.15));
		if(highscorePanel!=null)
		{
			highscorePanel.setBounds(0, 0, this.getWidth(), this.getHeight());
		}
	}
	
	public void paintComponent(Graphics g) {
        super.paintComponent(g);       
		setComponentsBounds();
    	if(ReaktioPeli.debugUI)
    	{
    		//showCp, showTimeMeter, showPlayersPanel, showQuestionPanel
            Graphics2D g2 = (Graphics2D) g;
            if(showCp)
            {
            	g2.drawRect(cp.getX()-1, cp.getY()-1, 
            			cp.getWidth()+2, cp.getHeight()+2);
            }
            /*
            if(showTimeMeter)
            {
            	g2.drawRect(timeMeter.getX()-1, timeMeter.getY()-1, 
            			timeMeter.getWidth()+2, timeMeter.getHeight()+2);
            }
            */
            if(showPlayersPanel)
            {
            	g2.drawRect(playersPanel.getX()-1, playersPanel.getY()-1, 
            			playersPanel.getWidth()+2, playersPanel.getHeight()+2);
            }
            if(showQuestionPanel)
            {
            	g2.drawRect(questionPanel.getX()-1, questionPanel.getY()-1, 
            			questionPanel.getWidth()+2, questionPanel.getHeight()+2);
            }
    	}
	}
	
	@Override
	public void setGameSettings(String setupFileName) {
		ReactionGameSettings settings = null;
		try {
			settings = (ReactionGameSettings) SettingsReader.getInstance().readSettings(
					setupFileName, ReactionGameSettings.class);
		} catch (JAXBException e) {
			e.printStackTrace();
			return;
		} catch (IOException e) {
			e.printStackTrace();
			return;
		}
		
		if(settings!=null && settings.getFontData()!=null && 
				settings.getFontData().getColor()!=null) {
			try {
				Color color = Color.decode(settings.getFontData().getColor());
				this.setForeground(color);
				cp.setForeground(color);
				//timeMeter.setForeground(color);
				playersPanel.setForeground(color);
				questionPanel.setForeground(color);
				gameOptionsPanel.setForeground(color);
				gameInstructionsPanel.setForeground(color);
				highscorePanel.setForeground(color);
				
				System.out.println("Color is " + color.toString());
			}
			catch(NumberFormatException e) {
				e.printStackTrace();
			}
			Font font = Font.decode(settings.getFontData().getName()+" "+
					settings.getFontData().getStyle()+" 40");
			if(font!=null) {
				this.setFont(font);
				//showCp, showTimeMeter, showPlayersPanel, showQuestionPanel
				cp.setFont(font);
				//timeMeter.setFont(font);
				playersPanel.setFont(font);
				questionPanel.setFont(font);
				gameOptionsPanel.setFont(font);
				gameInstructionsPanel.setFont(font);
				highscorePanel.setFont(font);
				System.out.println("Font is " + font.toString());
			}
			else
			{
				System.out.println("Creating font " + settings.getFontData().getName()+" "+
						settings.getFontData().getStyle() + " failed");
			}
		}
		else if(setupData!=null && setupData.getFontData()!=null && 
				setupData.getFontData().getColor()!=null) {
			try {
				Color color = Color.decode(setupData.getFontData().getColor());
				this.setForeground(color);
				cp.setForeground(color);
				//timeMeter.setForeground(color);
				playersPanel.setForeground(color);
				questionPanel.setForeground(color);
				gameOptionsPanel.setForeground(color);
				gameInstructionsPanel.setForeground(color);
				highscorePanel.setForeground(color);
				System.out.println("Color is " + color.toString());
			}
			catch(NumberFormatException e) {
				e.printStackTrace();
			}
			Font font = Font.decode(setupData.getFontData().getName()+" "+
					setupData.getFontData().getStyle()+" 40");
			if(font!=null) {
				this.setFont(font);
				//showCp, showTimeMeter, showPlayersPanel, showQuestionPanel
				cp.setFont(font);
				//timeMeter.setFont(font);
				playersPanel.setFont(font);
				questionPanel.setFont(font);
				gameOptionsPanel.setFont(font);
				gameInstructionsPanel.setFont(font);
				highscorePanel.setFont(font);
				System.out.println("Font is " + font.toString());
			}
			else
			{
				System.out.println("Creating font " + setupData.getFontData().getName()+" "+
						setupData.getFontData().getStyle() + " failed");
			}
		}

		if(settings!=null && settings.getQuestionsFontData()!=null) {
			Font font = Font.decode(settings.getQuestionsFontData().getName()+" "+
					settings.getQuestionsFontData().getStyle()+" 40");
			if(font!=null) {
				questionPanel.setQuestionsFont(font);
				System.out.println("Questions font is " + font.toString());
			}
			else
			{
				System.out.println("Creating questions font " + settings.getQuestionsFontData().getName()+" "+
						settings.getQuestionsFontData().getStyle() + " failed");
			}
			if(settings.getQuestionsFontData().getColor()!=null)
			{
				try {
					Color color = Color.decode(settings.getQuestionsFontData().getColor());
					questionPanel.setQuestionsFontColor(color);
					System.out.println("Color is " + color.toString());
				}
				catch(NumberFormatException e) {
					e.printStackTrace();
				}
			}
		}
		
		ArrayList<ChoiceButton> choiceButtons = settings.getChoiceButtons();
		cp.reset();
		cp.setVisible(false);
		cp.setFont(this.getFont());
		cp.setForeground(getForeground());
		if(choiceButtons!=null) {
			cp.setButtons(choiceButtons);
			choiceCount = choiceButtons.size();
		}

		
		if(this.userList!=null) {
			String setSaveFilePath;
			int controllerIndex = 0;
			
			// Modified 12.2012 to add mouse and additional keyboard settings
			//ArrayList<String> controls = setupData.getKeys(); The old method to get controls..
			int pelaajia               = userList.size();
			ArrayList<String> controls = setupData.getNewKeys(pelaajia); // The new method to get different keys for one and two player modes	
			String mouseConf = setupData.getMouseConfiguration(pelaajia);
			// modified 1.2013 Pekka: null check and default value
			if (mouseConf == null || mouseConf.equals("off")) {
				whoIsUsingTheMouse     = NO_ONE;
			}
			else if (setupData.getMouseConfiguration(pelaajia).equals("pelaaja2")) {
				whoIsUsingTheMouse     = PLAYER_2;
			} 
			else if (setupData.getMouseConfiguration(pelaajia).equals("pelaaja1") || setupData.getMouseConfiguration(pelaajia).equals("on")) {
				whoIsUsingTheMouse     = PLAYER_1;
			}		
			else
			{
				whoIsUsingTheMouse     = NO_ONE;
				
			}
			
			
			if(controls!=null && !userList.isEmpty()) {
				int ctrlCount = controls.size() / userList.size();
				choiceCount = choiceCount>ctrlCount?ctrlCount:choiceCount;
			}
			Iterator<UserSetting> iterator = userList.iterator();
			while(iterator.hasNext()) {
				UserSetting userSetting = iterator.next();
				Player player = new Player(midiSounds, this);
				player.setFolder(userSetting.getUserFolder());
				playersPanel.addPlayer(player);
				if(controls!=null) {
					ArrayList<String> playerControls = new ArrayList<String>();
					for(int i=0;i<choiceCount;i++) {
						playerControls.add(controls.get(controllerIndex));
						controllerIndex++;
					}
					player.setControls(playerControls);
				}
				player.setPlayerName(userSetting.getName());
				player.setPlayerImage(userSetting.getMenuImage());
				player.setOmitMistakes(settings.isOmitMistakes());
			}
			if(userList.size()==1)
			{
				setSaveFilePath = userList.get(0).getUserFolder();
			}
			else
			{
				setSaveFilePath = "./data/";
				List<String> nameList = new ArrayList<String>();
				for(int i=0;i<userList.size(); i++)
				{
					nameList.add(userList.get(i).getName());
				}
				Collections.sort(nameList);
				for(int i=0;i<nameList.size(); i++)
				{
					setSaveFilePath = setSaveFilePath + nameList.get(i);
				}
			}
			setSaveFilePath = setSaveFilePath.trim();
			if(setSaveFilePath.endsWith("/"))
			{
				gr.setSaveFile(setSaveFilePath+"playerdata.xml");
			}
			else
			{
				gr.setSaveFile(setSaveFilePath+"/playerdata.xml");
			}
		}
		else {
			choiceCount = 0;
			gr.setSaveFile("./data/unknown/playerdata.xml");
		}

		correctAnswerImg = MediaLoader.createImage(settings.getCorrectAnswerImage(), 600, 600);
		
		if(settings.getQuestions()!= null && settings.getQuestions().size()>0) {
			if(choiceCount>settings.getQuestions().size()) {
				choiceCount=settings.getQuestions().size();
			}
			cp.setChoiceQuestions(settings.getQuestions());
			cp.setVisible(true);
			showCp = true;
		}
		else if(whoIsUsingTheMouse!=NO_ONE)
		{
			cp.setVisible(true);
			showCp = true;
		}
		else
		{
			showCp = false; 			
		}
		
		cp.setMouseUser(whoIsUsingTheMouse);
		
		this.gr.setModel(settings, setupFileName);
		cp.setMaxShownButtonsCount(choiceCount);
		gameInstructionsPanel.setButtonImages(cp.getCurrentOriginalImages());		

		playersPanel.setShowScore(settings.isShowScore());
		playersPanel.setVisible(true);
		showPlayersPanel = true;
		
		questionPanel.setInstruction(null);
		questionPanel.setQuestion(null);
		questionPanel.setVisible(true);
		showQuestionPanel = true;
		
		setComponentsBounds();
	}


	@Override
	public void setLanguage(String languageFileName)
	{
		LanguageSettings languageSettings = null;
		try {
			languageSettings = (LanguageSettings) SettingsReader.getInstance().readSettings(
					languageFileName, LanguageSettings.class);
		} catch (JAXBException e) {
			e.printStackTrace();
			return;
		} catch (IOException e) {
			e.printStackTrace();
			return;
		}

		Iterator<KeyValuePair> it = languageSettings.getValueList().iterator();
		while(it.hasNext()) {
			KeyValuePair value = it.next();
			LanguageResource lr = LanguageResource.getInstance();
			lr.setValue(value.getKey(), value.getValue());
		}
		if(gameOptionsPanel!=null) 
		{
			gameOptionsPanel.refreshLanguage();
		}
		if(gameInstructionsPanel!=null) 
		{
			gameInstructionsPanel.refreshLanguage();
		}
		if(highscorePanel!=null) 
		{
			highscorePanel.refreshLanguage();
		}
	}

	@Override
	public void startGame() {
		this.requestFocus();
		playersPanel.resetPlayers(gr, this);
		gr.gameStart();
	}

	@Override
	public void gameEnd() {
		midiSounds.removeNotes();
		playersPanel.clearPlayers(gr);
		if(gameOptionsPanel.isVisible())
			hideSetup();
		if(gameInstructionsPanel.isVisible())
			hideInstructionsPanel();
		if(highscorePanel.isVisible())
			hideHighScore();
		this.choiceCount = 0;
		this.endClip = null;
		this.cp.reset();
		//this.timeMeter.setVisible(false);
		this.cp.setVisible(false);
		this.playersPanel.setVisible(false);
		this.questionPanel.setInstruction(null);
		this.questionPanel.setQuestion(null);
		this.questionPanel.setVisible(false);
		super.gameEnd();
	}

	public Clip showChoices(int rightAnswer, String instruction) {
		Clip sound = null;
		cp.clearAllTargets();
		cp.shuffleChoices();
		cp.setTarget(rightAnswer);
		questionPanel.setInstruction(instruction);
		MediaElement me = cp.getButtonQuestion(rightAnswer);
		questionPanel.setQuestion(me);
		if(me!=null) {
			sound = me.getSound();
		}
		else {
			sound = null;
		}
		
		//playClip(sound);
		playersPanel.setAnswer(rightAnswer);
		return sound;
	}
	
	protected void playClip(Clip clip) {	
		if(clip!=null) {
			if(!clip.isActive()) {
				clip.setMicrosecondPosition(0);
				clip.start();
				try {
					Thread.sleep(30);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
			while(clip.isActive()) {
				try {
					Thread.sleep(30);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				if(!gr.isRunning()) {
					clip.stop();
				}
			}
		}
	}

	public void showWait() {
		questionPanel.setQuestion(null);
		questionPanel.setInstruction(null);
	}

	public void showFeedback(String feedback, boolean showCorrectAnswerImg) {
		MediaElement me = null;
		if(showCorrectAnswerImg && correctAnswerImg!=null)
		{
			me = new MediaElement();
			me.setImage(correctAnswerImg);
		}
		questionPanel.setQuestion(me);
		questionPanel.setInstruction(feedback);
	}
	
	public void playEndClip()
	{
		Thread t = new Thread(new Runnable() {

			@Override
			public void run() {
				playClip(endClip);
			}});
		t.start();
	}

	@Override
	public void keyPressed(KeyEvent e) {
		// Kun painetaan control + n lopetetaan peli
		if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_N) {		
			gr.gameOver();
		}
		// Kun painetaan esc lopetetaan peli
		if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {		
			gr.gameOver();
		}
	}

	@Override
	public void keyReleased(KeyEvent e) {
		// ei tarvetta.
	}

	@Override
	public void keyTyped(KeyEvent e) {
		// ei tarvetta.
	}

	/*
	public void showTimeMeter(long timeLeft, long totalTime) {
		if(!showTimeMeter) return;
		timeMeter.setTime(timeLeft, totalTime);
		timeMeter.setVisible(true);
		playersPanel.setTotalTime(totalTime);
	}
	*/
	
	public void newRound(long totalTime) {
		playersPanel.setMaxRoundTime(totalTime);
		playersPanel.newRound();
	}

	/*
	public void hideTimeMeter() {
		timeMeter.setVisible(false);
	}
	*/


	public void clearTargets() {
		playersPanel.clearTargets();
	}


	public int getCountOfFailedPlayers() 
	{
		return playersPanel.getCountOfFailedPlayers();
	}
	
	public int getCountOfSucceededPlayers() 
	{
		return playersPanel.getCountOfSucceededPlayers();
	}

	public int getCountOfPlayers() {
		return playersPanel.getCountOfPlayers();
	}

	public int getChoiceCount() {
		return choiceCount;
	}
	

	public void showInstructionsPanel() {
		cp.setVisible(false);
		gameInstructionsPanel.setEnabled(true);
		//this.setComponentZOrder(optionsPanel, 0);
		gameInstructionsPanel.setVisible(true);
	}


	public void hideInstructionsPanel() {
		gameInstructionsPanel.setVisible(false);
		gameInstructionsPanel.setEnabled(false);
		if(showCp) {
			cp.setVisible(true);
		}
		this.requestFocus();
		setComponentsBounds();
	}
	

	public void showSetup(SetupData setupData) {
		cp.setVisible(false);
		gameOptionsPanel.setSetupData(setupData);
		gameOptionsPanel.setEnabled(true);
		//this.setComponentZOrder(optionsPanel, 0);
		gameOptionsPanel.setVisible(true);
	}


	public void hideSetup() {
		gameOptionsPanel.setVisible(false);
		gameOptionsPanel.setEnabled(false);
		if(showCp) {
			cp.setVisible(true);
		}
		this.requestFocus();
		setComponentsBounds();
	}

	public void setShowScore(boolean showScore) {
		playersPanel.setShowScore(showScore);
	}

	public String getButtonNameById(int i) {
		return cp.getButtonName(i);
	}

	public void logAllPlayers(String string) {
		playersPanel.logAllPlayers(string);
	}

	public void setMaxRounds(int maxRounds) {
		playersPanel.setMaxScore(maxRounds);
		playersPanel.showTimeMeter(maxRounds>0);
	}

	public void setOmitMistakes(boolean omitMistakes) {
		playersPanel.setOmitMistakes(omitMistakes);
		
	}

	public void setCorrectAnswerImage(String correctAnswerImage) {
		this.correctAnswerImg = MediaLoader.createImage(correctAnswerImage, 600, 600);
	}

	/**
	 * 
	 * @param gameTime questions time for last time in milliseconds
	 */
	public void refreshGameTime(long gameTime) {
		playersPanel.addPlayedTime(gameTime);
		
	}

	public ArrayList<Player> getPlayers() {
		return playersPanel.getPlayers();
		
	}

	public void showHighScore(DIFFICULTY difficulty, Hashtable<Player, HighScore> saveHighScores) {
		//this.midiSounds.playNotes();
		highscorePanel.setScores(difficulty, saveHighScores);
		highscorePanel.setVisible(true);
	}

	public void hideHighScore() {
		highscorePanel.setVisible(false);
		setComponentsBounds();
	}

	public void refreshSetupData(SetupData setupData) {
		setMaxRounds(setupData.getGameDifficulty().getRounds());
		setOmitMistakes(setupData.isOmitMistakes());
		setCorrectAnswerImage(setupData.getCorrectAnswerImage());
		if(setupData.getGameDifficulty()!=null && setupData.getGameDifficulty().getRounds()>0) {
			playersPanel.showTimeMeter(false);
		}
		else {
			playersPanel.showTimeMeter(true);
		}
	}

	public void setShowTime(boolean showTime) {
		playersPanel.setShowTime(showTime);
	}

}
